package com.seng.resourcetycoon.gui.controllers;

import com.seng.resourcetycoon.core.entities.GameConfiguration;
import com.seng.resourcetycoon.core.enums.DifficultyLevel;
import com.seng.resourcetycoon.core.enums.TowerState;
import com.seng.resourcetycoon.factory.TowerFactory;
import com.seng.resourcetycoon.gui.models.ResourceTower;
import com.seng.resourcetycoon.gui.views.TowerSetupCellView;
import com.seng.resourcetycoon.manager.GameEnvironment;
import com.seng.resourcetycoon.util.DataValidator;
import com.seng.resourcetycoon.util.SceneUtil;
import com.seng.resourcetycoon.util.ToastUtil;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;

public class GameSetupController {

    @FXML
    private ListView<ResourceTower> towerListView;
    @FXML
    private RadioButton easy;
    @FXML
    private RadioButton normal;
    @FXML
    private RadioButton hard;
    @FXML
    private Slider roundNumber;
    @FXML
    private TextField name;
    private final ToggleGroup toggleGroup = new ToggleGroup();
    private TowerFactory towerFactory;

    @FXML
    private void initialize() {
        towerFactory = new TowerFactory();
        populateTowersList();
        configureTowerListView();
        setupDifficultyToggles();
    }

    @FXML
    private void onBtnSaveClick(ActionEvent event) {
        try {
            validateAndSetPlayerName(name.getText());
            List<ResourceTower> selectResourceTowers = towerListView.getSelectionModel().getSelectedItems();

            validateAndSetSelectedTowers();
            setGameConfiguration();

            //fixed readonly list
            GameEnvironment.getInstance().setTowers(new ArrayList<>(selectResourceTowers));
            SceneUtil.getInstance().closeCurrent();
            SceneUtil.getInstance().switchToGamePlay();
        } catch (IllegalArgumentException ex) {
            ToastUtil.showAlert(ex.getMessage(), "Validation Error");
            return;
        }
    }


    private void validateAndSetPlayerName(String playerName) throws IllegalArgumentException {
        if (!DataValidator.validatePlayerName(playerName)) {
            throw new IllegalArgumentException("Username is invalid.");
        }

        GameEnvironment.getInstance().setPlayerName(playerName);
    }

    private void validateAndSetSelectedTowers() throws IllegalArgumentException {
        List<ResourceTower> selectedResourceTowers = towerListView.getSelectionModel().getSelectedItems();

        if (selectedResourceTowers.isEmpty()) {
            throw new IllegalArgumentException("No tower selected.");
        }

        if(selectedResourceTowers.size() > 3){
            throw new IllegalArgumentException("The number of selected resourceTowers cannot exceed 3.");
        }
    }

    private void setGameConfiguration() {
        GameConfiguration gameConfiguration = new GameConfiguration();

        DifficultyLevel selectedDifficulty = (DifficultyLevel) toggleGroup.getSelectedToggle().getUserData();
        gameConfiguration.setDifficultyLevel(selectedDifficulty);
        gameConfiguration.setNumberOfRounds(roundNumber.valueProperty().intValue());

        GameEnvironment.getInstance().setGameConfiguration(gameConfiguration);
    }

    private void populateTowersList() {
        ObservableList<ResourceTower> resourceTowers = FXCollections.observableArrayList();
        for (int i = 0; i < 6; i++) {
            ResourceTower resourceTower = towerFactory.createTower();
            resourceTower.setState(TowerState.ACTIVE);
            resourceTowers.add(resourceTower);
        }
        towerListView.setItems(resourceTowers);
    }

    private void configureTowerListView() {
        towerListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        towerListView.setCellFactory(towerListView -> new TowerSetupCellView());
    }

    private void setupDifficultyToggles() {
        Map<DifficultyLevel, RadioButton> difficultyRadios = new EnumMap<>(DifficultyLevel.class);
        difficultyRadios.put(DifficultyLevel.EASY, easy);
        difficultyRadios.put(DifficultyLevel.MEDIUM, normal);
        difficultyRadios.put(DifficultyLevel.HARD, hard);

        for (Map.Entry<DifficultyLevel, RadioButton> entry : difficultyRadios.entrySet()) {
            RadioButton radioButton = entry.getValue();
            radioButton.setToggleGroup(toggleGroup);
            radioButton.setUserData(entry.getKey());
        }
    }

}
